-- i26_jianmu_data.lua
-- 定义 i26_jianmu_data 类，用于管理建木的特效状态

local i26_jianmu_data = Class(function(self, inst)
    self.inst = inst
    -- 标识当前对象是树苗还是建木
    self.is_sapling = false
    -- 特效状态
    self.effects = {
        i26_nuanlu = {
            active = false,
            materials = {
                dragon_scales = { progress = 0, required = 1 },
            },
            dependencies = {}
        },
        i26_fangshui = {
            active = false,
            materials = {
                deerclops_eyeball = { progress = 0, required = 1 },
            },
            dependencies = {}
        },
        i26_hanbing = {
            active = false,
            materials = {
                blueamulet = { progress = 0, required = 5 }, -- 寒冰护符
            }
        },
        i26_zhiwu1 = {
            active = false,
            materials = {
                treegrowthsolution = { progress = 0, required = 1 }, -- 树果酱
            },
            dependencies = {}
        },
        i26_zhiwu2 = {
            active = false,
            materials = {
                treegrowthsolution = { progress = 0, required = 10 }, -- 树果酱
            },
            dependency = { "i26_zhiwu1" }                             -- 依赖于 i26_zhiwu1 特效
        },
        i26_fengraoxuanshu = {
            active = false,
            materials = {
                amulet = { progress = 0, required = 8 }, -- 重生护符
            },
            dependency = {}
        },
        i26_restore_san = { -- 恢复精神值
            active = false,
            materials = {
                yellowamulet = { progress = 0, required = 5 }, -- 魔光护符
            },
            dependency = {}
        }

    }
    -- 材料名反查特效
    self.material_to_effects = {}
    -- 特效激活顺序
    self.sorted_effects = {
        "i26_nuanlu",
        "i26_fangshui",
        "i26_hanbing",
        "i26_zhiwu1",
        "i26_zhiwu2",
        "i26_fengraoxuanshu",
        "i26_restore_san",
    }
    -- 获取有效范围配置
    self.range = TUNING.JIANMU_CONFIG.EFFECTIVE_RADIUS
    -- 初始化材料名反查特效
    self:InitializeMaterialToEffects()
    self.check_temperature_task = nil
    -- 植物催熟定时任务
    self.try_growth_for_entities_temperature_task = nil
    -- 丰饶玄术定时任务
    self.i26_fengraoxuanshu_temperature_task = nil
    -- 初始化定时任务
    self:initTemperatureTask(inst)
end)
-- 摘抄小穹空白魔法的
local function fixCostController(self)
    self.donemoisture = true
    self.donenutrient = true
    self.donetendable = true
end

function i26_jianmu_data:initTemperatureTask(inst)
    if self.check_temperature_task ~= nil then
        self.check_temperature_task:Cancel()
        self.check_temperature_task = nil
    end
    if not self.is_sapling and TUNING.JIANMU_CONFIG.ENABLED_JIANMU then
        self.check_temperature_task = inst:DoPeriodicTask(3, function()
            if not TUNING.JIANMU_CONFIG.ENABLED_JIANMU then
                self:OnDestroy()
            end
            if inst.components.i26_jianmu_data then
                -- 在这里添加其他特效的检查和激活逻辑
                inst.components.i26_jianmu_data:ApplyEffect(inst)
            end
        end)
    end
end

-- 初始化材料名反查特效
function i26_jianmu_data:InitializeMaterialToEffects()
    for effect_name, effect_data in pairs(self.effects) do
        for material_name, _ in pairs(effect_data.materials) do
            if not self.material_to_effects[material_name] then
                self.material_to_effects[material_name] = {}
            end
            table.insert(self.material_to_effects[material_name], effect_name)
        end
    end
end


-- 拒绝接收物品
function i26_jianmu_data:OnRefuseItem(inst, giver, item)
    if inst.components.talker then
        inst.components.talker:Say(TUNING.STRINGS[TUNING.LANGUAGE].jianmu_buff_not_item)
    end
end

-- 检查物品是否可接受
function i26_jianmu_data:CanAcceptItem(inst, item, giver)
    local material_name = item.prefab
    -- 针对为爽模组 给予告密的心
    if TUNING.JIANMU_CONFIG.I26_LINKAGE_WEISHUANG_ENABLED and material_name == "reviver" then
        return true
    end
    local effect_names = self.material_to_effects[material_name]
    if not effect_names then
        if giver.components.talker then
            giver.components.talker:Say(TUNING.STRINGS[TUNING.LANGUAGE].jianmu_buff_not_item)
        end
        return false
    end

    local can_accept = false
    local first_unactivated_dependency = nil

    for _, effect_name in ipairs(self.sorted_effects) do
        if table.contains(effect_names, effect_name) then
            local effect_data = self.effects[effect_name]
            local dependencies = effect_data.dependencies or {}

            local can_process = true
            for _, dependency in ipairs(dependencies) do
                if not self.effects[dependency].active then
                    can_process = false
                    if not first_unactivated_dependency then
                        first_unactivated_dependency = dependency
                    end
                    break
                end
            end

            if can_process then
                local material_data = effect_data.materials[material_name]
                if not effect_data.active and material_data.progress < material_data.required then
                    -- 优先激活没有依赖的特效
                    if #dependencies == 0 then
                        return true
                    end
                    can_accept = true
                end
            end
        end
    end

    if not can_accept and giver.components.talker then
        if first_unactivated_dependency then
            giver.components.talker:Say(TUNING.STRINGS[TUNING.LANGUAGE].jianmu_buff_not_pre_effect ..
                    " " .. TUNING.JIANMU_BUFF[TUNING.LANGUAGE][first_unactivated_dependency])
        else
            giver.components.talker:Say(TUNING.STRINGS[TUNING.LANGUAGE].jianmu_buff_not_item)
        end
    end

    return can_accept
end

-- 恢复最大生命值
function i26_jianmu_data:ResetMaxValues(player)
    if player.components.hunger and player.components.hunger.SetPenalty2hm then
        player.components.hunger:SetPenalty2hm(0)
    end
    -- 重置玩家的生命值上限到初始状态
    if player.components.health then
        player.components.health:SetPenalty(0)  -- 重置惩罚
        player.components.health:ForceUpdateHUD(true)  -- 更新 HUD
    end
end

-- 更新特效进度
function i26_jianmu_data:UpdateEffectProgress(inst, giver, item)
    local material_name = item.prefab
    -- 针对为爽模组 给予告密的心
    -- 针对为爽模组 给予告密的心
    if TUNING.JIANMU_CONFIG.I26_LINKAGE_WEISHUANG_ENABLED and material_name == "reviver" then
        -- 重置玩家的生命值上限到初始状态
        self:ResetMaxValues(giver)
        return true
    end
    local effect_names = self.material_to_effects[material_name]

    -- 只更新无依赖或依赖已满足的特效
    for _, effect_name in ipairs(self.sorted_effects) do
        if table.contains(effect_names, effect_name) then
            local effect_data = self.effects[effect_name]
            local dependencies = effect_data.dependencies or {}

            local can_process = true
            for _, dependency in ipairs(dependencies) do
                if not self.effects[dependency].active then
                    can_process = false
                    break
                end
            end

            if can_process then
                local material_data = effect_data.materials[material_name]
                if not effect_data.active and material_data.progress < material_data.required then
                    material_data.progress = material_data.progress + 1
                    if material_data.progress >= material_data.required then
                        effect_data.active = true
                        if giver.components.talker then
                            giver.components.talker:Say(TUNING.JIANMU_BUFF[TUNING.LANGUAGE][effect_name] ..
                                    " " .. TUNING.STRINGS[TUNING.LANGUAGE].jianmu_buff_is_active)
                        end
                    else
                        if giver.components.talker then
                            giver.components.talker:Say(TUNING.JIANMU_BUFF[TUNING.LANGUAGE][effect_name] ..
                                    ": " .. material_data.progress .. "/" .. material_data.required)
                        end
                    end
                    return true
                end
            end
        end
    end

    return false
end

-- 3 秒执行一次的定时任务
function i26_jianmu_data:ApplyEffect(inst)
    -- 只有在不是树苗的情况下才应用特效
    if not self.is_sapling and TUNING.JIANMU_CONFIG.ENABLED_JIANMU then
        if self.effects.i26_hanbing.active and TUNING.JIANMU_CONFIG.I26_HANBING_ENABLED then
            self:ApplyHanbingEffect(inst, self.range)
        end
        if TUNING.JIANMU_CONFIG.I26_ZHIWU1_ENABLED and self.effects.i26_zhiwu1.active and self.try_growth_for_entities_temperature_task == nil then
            -- 重新开个催熟定时任务，催熟独立计算时间
            self.try_growth_for_entities_temperature_task = inst:DoPeriodicTask(TUNING.JIANMU_CONFIG.I26_ZHIWU_INTERVAL_TIME, function()
                -- 催熟作物和石果
                self:TryGrowthForEntities(inst, self.range, self.effects.i26_zhiwu2.active)
            end)
        end

        if (TUNING.JIANMU_CONFIG.I26_FENGRAOXUANSHU_ENABLED or TUNING.JIANMU_CONFIG.I26_RESTORE_SAN_ENABLED)
                and (self.effects.i26_fengraoxuanshu.active or self.effects.i26_restore_san.active)
                and self.i26_fengraoxuanshu_temperature_task == nil then
            -- 重新开个治疗回san定时任务
            self.i26_fengraoxuanshu_temperature_task = inst:DoPeriodicTask(5, function()
                -- 治疗/回san 周围玩家
                self:TreatmentForEntities(inst, self.range)
            end)
        end
        if (self.effects.i26_nuanlu.active and TUNING.JIANMU_CONFIG.I26_NUANLU_ENABLED)
                or (self.effects.i26_hanbing.active and TUNING.JIANMU_CONFIG.I26_HANBING_ENABLED)
                or (self.effects.i26_fangshui.active and TUNING.JIANMU_CONFIG.I26_FANGSHUI_ENABLED) then
            self:ApplyEffectBuff(inst, self.range)
        end
    end
end

function i26_jianmu_data:ApplyEffectBuff(inst, range)
    -- 定义不能包含的标签
    local GARDENING_CANT_TAGS = { "INLIMBO", "stump", "barren" }
    -- 定义必须包含的标签（只查找玩家）
    local PLAYER_TAGS = { "player" }
    -- 获取当前实体的位置
    local x, y, z = inst.Transform:GetWorldPosition()
    -- 查找范围内的玩家实体
    local players = TheSim:FindEntities(x, y, z, range, PLAYER_TAGS, GARDENING_CANT_TAGS)
    if players and #players > 0 then
        for _, player in ipairs(players) do
            -- 检查玩家是否有debuffable组件
            if player.components.debuffable then
                -- 添加buff，假设buff的ID是"i26_warmthdebuff"
                if self.effects.i26_nuanlu.active then
                    local buffId = TUNING.ENTITY_LIST.WARMTHDE_BUFF.id
                    player.components.debuffable:AddDebuff(buffId, buffId)
                end
                if self.effects.i26_hanbing.active then
                    local buffId = TUNING.ENTITY_LIST.HANBING_BUFF.id
                    player.components.debuffable:AddDebuff(buffId, buffId)
                end
                if self.effects.i26_fangshui.active then
                    local buffId = TUNING.ENTITY_LIST.FANGSHUI_BUFF.id
                    player.components.debuffable:AddDebuff(buffId, buffId)
                end
            end
        end
    end
end

function i26_jianmu_data:TreatmentForEntities(inst, range)
    -- 定义不能包含的标签
    local GARDENING_CANT_TAGS = { "INLIMBO", "stump", "barren" }
    -- 定义必须包含的标签（只查找玩家）
    local PLAYER_TAGS = { "player" }
    -- 获取当前实体的位置
    local x, y, z = inst.Transform:GetWorldPosition()
    -- 查找范围内的玩家实体
    local players = TheSim:FindEntities(x, y, z, range, PLAYER_TAGS, GARDENING_CANT_TAGS)
    if players and #players > 0 then
        for _, player in ipairs(players) do
            -- 检查玩家是否有血量组件，是否死亡
            if TUNING.JIANMU_CONFIG.I26_FENGRAOXUANSHU_ENABLED and self.effects.i26_fengraoxuanshu.active then
                if player.components.health and not player.components.health:IsDead() then
                    player.components.health:DoDelta(3)
                end
            end
            -- 检查玩家是否有精神值组件，是否死亡
            if TUNING.JIANMU_CONFIG.I26_RESTORE_SAN_ENABLED and self.effects.i26_restore_san.active then
                if player.components.sanity and not player.components.health:IsDead() then
                    player.components.sanity:DoDelta(3) -- 恢复3点精神值
                end
            end

        end
    end
end

-- 尝试催熟作物和石果
function i26_jianmu_data:TryGrowthForEntities(inst, range, effect2_active)
    if not inst.components then
        return
    end
    local GARDENING_CANT_TAGS = { "INLIMBO", "stump" }
    local GARDENING_ONEOF_TAGS = { "plant", "crop", "growable","barren","perennialcrop","perennialcrop2", "harvestable", "silviculture" }
    local x, y, z = inst.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, range, nil, GARDENING_CANT_TAGS, GARDENING_ONEOF_TAGS)
    for _, ent in ipairs(ents) do
        if ent:IsValid() and not ent:IsInLimbo() then
            -- 处理树精
            if ent:HasTag("leif") then
                ent.components.sleeper:GoToSleep(3000)
            else
                -- 农作物巨大代码
                if effect2_active and TUNING.JIANMU_CONFIG.I26_ZHIWU2_ENABLED then
                    -- 兼容棱镜子圭垄进行设置
                    if ent.components.perennialcrop2 then
                        ent.components.perennialcrop2.pollinated_max = -1
                        ent.components.perennialcrop2.infested_max = 100
                        ent.components.perennialcrop2.getsickchance = 0
                        ent.components.perennialcrop2.CostController = fixCostController
                        ent.components.perennialcrop2.CostNutrition = fixCostController
                        ent.components.perennialcrop2:CostNutrition()
                        ent.components.perennialcrop2:CostController()
                    end
                    if ent.components.perennialcrop then
                        ent.components.perennialcrop.sorafix = 1
                        ent.components.perennialcrop.moisture = 999 -- 当前水量
                        ent.components.perennialcrop.nutrient = 999 -- 当前肥量（生长必需）
                        ent.components.perennialcrop.nutrientgrow = 999 -- 当前肥量（生长加速）
                        ent.components.perennialcrop.nutrientsick = 999 -- 当前肥量（预防疾病）
                        ent.components.perennialcrop.sickness = 0 -- 当前病害程度
                        ent.components.perennialcrop.infested = 0 -- 被骚扰次数
                        ent.components.perennialcrop.nosick = true   --无虫害
                        ent.components.perennialcrop.moisture_max = 999 -- 最大蓄水量
                        ent.components.perennialcrop.nutrient_max = 999 -- 最大蓄肥量（生长必需）
                        ent.components.perennialcrop.nutrientgrow_max = 999 -- 最大蓄肥量（生长加速）
                        ent.components.perennialcrop.nutrientsick_max = 999 -- 最大蓄肥量（预防疾病）
                        ent.components.perennialcrop.pollinated_max = 0 -- 被授粉次数大于等于该值就能增加产量
                        ent.components.perennialcrop.infested_max = 1000 -- 被骚扰次数大于等于该值就会立即进入腐烂/枯萎阶段
                        ent.components.perennialcrop.cost_moisture = 0 -- 需水量
                        ent.components.perennialcrop.cost_nutrient = 0 -- 需肥类型(这里只需要一个量即可，不需要关注肥料类型)
                        ent.components.perennialcrop.can_getsick = false -- 是否能产生病虫害（原创）
                        ent.components.perennialcrop.killjoystolerance = 3 -- 扫兴容忍度：一般都为0
                    end
                    ent.force_oversized = true
                end
                -- 处理 growable 组件 更高级的作物催熟组件
                local growable = ent.components.growable
                if growable ~= nil and not ent:HasTag("stump") then
                    local stage = growable.stage
                    local max_stage = #growable.stages
                    local isTree = ent:HasTag("tree") or ent:HasTag("winter_tree") or ent:HasTag("siving_derivant")
                    local isSpecialPlant = ent:HasTag("farm_plant_immortal_fruit")
                            or ent:HasTag("farm_plant_medal_gift_fruit")
                            or ent.prefab == "farm_plant_randomseed" -- 种子也没有枯萎阶段
                    if ((isTree and not ent:HasTag("stump"))) then
                        if stage < max_stage or ent:HasTag("siving_derivant") then
                            if ent.components.simplemagicgrower ~= nil then
                                ent.components.simplemagicgrower:StartGrowing()
                            elseif growable.domagicgrowthfn ~= nil then
                                growable:DoMagicGrowth()
                            else
                                growable:DoGrowth()
                            end
                        end
                    elseif ent:HasTag("farm_plant") then
                        -- 把农锁在这
                        if (stage < (max_stage - 1) or (isSpecialPlant and stage < max_stage)) then
                            growable:DoGrowth()
                        end
                    else
                        if ent.components.simplemagicgrower ~= nil then
                            ent.components.simplemagicgrower:StartGrowing()
                        elseif growable.domagicgrowthfn ~= nil then
                            growable:DoMagicGrowth()
                        else
                            growable:DoGrowth()
                        end
                    end
                elseif ent.components.pickable ~= nil then
                    if not (ent.components.pickable:CanBePicked() and ent.components.pickable.caninteractwith) then
                        if ent.components.pickable:FinishGrowing() then
                            ent.components.pickable:ConsumeCycles(1) -- magic grow is hard on plants
                        end
                    end
                elseif ent.components.crop ~= nil and (ent.components.crop.rate or 0) > 0 then
                    ent.components.crop:DoGrow(1 / ent.components.crop.rate, true)
                elseif ent.components.harvestable ~= nil and ent:HasTag("mushroom_farm") then
                    -- 蘑菇农场催熟逻辑
                    local harvestable = ent.components.harvestable
                    if harvestable:IsMagicGrowable() then
                        harvestable:DoMagicGrowth()
                    else
                        harvestable:Grow()
                    end
                end
            end
        end
    end
end

-- 寒冰特效
-- 扑灭附火焰，防止作物枯萎并持续生长，防止植物枯萎
function i26_jianmu_data:ApplyHanbingEffect(inst, range)
    -- 定义火焰相关的标签
    local canttags = { "INLIMBO", "lighter" }
    local findList = { "fire", "smolder", "pickable", "witherable", "stump", "_inventoryitem", "pickable", "harvestable",
                       "readyforharvest", "donecooking", "dried", "takeshelfitem", "witherable" }

    -- 寻找范围内的实体
    local x, y, z = inst.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, range, nil, canttags, findList)
    if ents and #ents > 0 then
        for _, ent in ipairs(ents) do
            if ent:HasTag("fire") or ent:HasTag("smolder") then
                if ent.components.burnable then
                    ent.components.burnable:Extinguish(true, 0)
                end
            end
            -- 防止作物枯萎并持续生长 pickable 植物组件
            if ent.components.pickable then
                ent.components.pickable:Resume()
            end
            if ent:HasTag("witherable") then
                if inst.components.wateryprotection then
                    inst.components.wateryprotection:SpreadProtection(ent)
                end
            end
            -- 检查植物是否处于枯萎状态
            if ent.components.witherable ~= nil and ent.components.witherable:IsWithered() then
                -- 解除枯萎状态
                ent.components.witherable:ForceRejuvenate()
            end
        end
    end
end

-- 保存特效状态
function i26_jianmu_data:OnSave()
    local data = {}
    for k, v in pairs(self.effects) do
        data[k] = { active = v.active, materials = {} }
        for mat_name, mat_data in pairs(v.materials) do
            data[k].materials[mat_name] = { progress = mat_data.progress }
        end
    end
    return data
end

-- 加载特效状态
function i26_jianmu_data:OnLoad(data)
    if data then
        for k, v in pairs(data) do
            if self.effects[k] then
                self.effects[k].active = v.active
                for mat_name, mat_data in pairs(v.materials) do
                    if self.effects[k].materials[mat_name] then
                        self.effects[k].materials[mat_name].progress = mat_data.progress
                    end
                end
            end
        end
    end
end

-- 在建木被摧毁时调用，移除所有特效和任务
function i26_jianmu_data:OnDestroy()
    -- 取消定时任务
    if self.check_temperature_task ~= nil then
        self.check_temperature_task:Cancel()
        self.check_temperature_task = nil
    end
    if self.try_growth_for_entities_temperature_task ~= nil then
        self.try_growth_for_entities_temperature_task:Cancel()
        self.try_growth_for_entities_temperature_task = nil
    end
    if self.i26_fengraoxuanshu_temperature_task ~= nil then
        self.i26_fengraoxuanshu_temperature_task:Cancel()
        self.i26_fengraoxuanshu_temperature_task = nil
    end
end

return i26_jianmu_data
